#include "TCPClient.h"
#include "ui_TCPClient.h"
#include <QHostInfo>
#include <QHostAddress>

TCPClient::TCPClient(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::TCPClient)
{
    ui->setupUi(this);

    initDataSlot();
}

TCPClient::~TCPClient()
{
    delete ui;
}

void TCPClient::initDataSlot()
{
    //创建Socket变量
    if(mTcpClient == nullptr)
    {
        mTcpClient = new QTcpSocket(this);
    }

    //设置服务端的ip和端口
    ui->lineEdit_serviceIP->setText(getLocalIP());
    ui->lineEdit_servicePort->setText(QString::number(PORT));
    misConnectService = false;
    ui->label_socketState->setText("Socket 状态:");

    //建立信号槽连接
    connect(mTcpClient, &QTcpSocket::connected, this, &TCPClient::onConnected);
    connect(mTcpClient, &QTcpSocket::disconnected, this, &TCPClient::onDisconnected);
    connect(mTcpClient, &QTcpSocket::stateChanged, this, &TCPClient::onSocketStateChange);
    connect(mTcpClient, &QTcpSocket::readyRead, this, &TCPClient::onSocketReadyRead);
}

QString TCPClient::getLocalIP()
{
    //获取本机IPv4地址
    QString hostName=QHostInfo::localHostName() ;//本地主机名
    QHostInfo hostInfo=QHostInfo::fromName (hostName) ;

    QString localIP="";
    QList<QHostAddress> addList=hostInfo.addresses () ;
    if (!addList. isEmpty())
    {
        for (int i=0; i <addList.count() ;i++)
        {
            QHostAddress aHost=addList.at(i) ;
            if (QAbstractSocket::IPv4Protocol == aHost. protocol())
            {
                localIP=aHost. toString() ;
                break;
            }
        }
    }

    return localIP;
}

void TCPClient::onConnected()
{
    //connected()信号槽函数
    ui->plainTextEdit->appendPlainText ("**已连接到服务器") ;
    ui ->plainTextEdit->appendPlainText ("**peer address:"+ mTcpClient->peerAddress().toString()) ;
    ui ->plainTextEdit->appendPlainText ("**peer port:"+ QString::number(mTcpClient->peerPort())) ;

}

void TCPClient::onDisconnected()
{
    //disConnected()信号槽函数
    ui->plainTextEdit->appendPlainText ("**已断开与服务器的连接") ;
}

void TCPClient::onSocketStateChange(QAbstractSocket::SocketState socketState)
{
    switch (socketState)
    {
    case QAbstractSocket::UnconnectedState:
        ui->label_socketState->setText ("socket状态: UnconnectedState") ;
        break;
    case QAbstractSocket::HostLookupState:
        ui->label_socketState->setText ("socket状态: HostLookupState") ;
        break;
    case QAbstractSocket::ConnectingState:
        ui->label_socketState->setText ("socket状态: ConnectingState") ;
        break;
    case QAbstractSocket::ConnectedState:
        ui->label_socketState->setText ("socket状态: ConnectedState") ;
        break;
    case QAbstractSocket::BoundState:
        ui->label_socketState->setText ("socket状态: BoundState") ;
        break;
    case QAbstractSocket::ClosingState:
        ui->label_socketState->setText ("socket状态: ClosingState") ;
        break;
    case QAbstractSocket::ListeningState:
        ui->label_socketState->setText ("socket状态: ListeningState") ;
        break;
    }
}

void TCPClient::onSocketReadyRead()
{
    //readyRead()信号槽函数
    while (mTcpClient->canReadLine())
    {
         ui->plainTextEdit->appendPlainText("[in] "+mTcpClient->readLine()) ;
    }
}


void TCPClient::on_pushButton_connectService_clicked()
{
    if(misConnectService)
    {
        misConnectService=  false;

        //断开服务器按钮
        mTcpClient->disconnectFromHost();
        ui->pushButton_connectService->setText("连接服务器");
    }
    else
    {
        misConnectService = true;
         //连接服务器按钮
        QString addr= ui->lineEdit_serviceIP->text();
        quint16  port=ui->lineEdit_servicePort->text().toInt();
        ui->pushButton_connectService->setText("断开服务器");
        mTcpClient->connectToHost (addr,port) ;
    }
}

void TCPClient::on_pushButton_sendMsg_clicked()
{
    //发送数据
    QString  msg=ui->lineEdit_msg->text() ;
    ui->plainTextEdit->appendPlainText ("[out] "+msg) ;
    ui->lineEdit_msg->clear() ;
    ui->lineEdit_msg->setFocus() ;
    QByteArray str=msg.toUtf8() ;
    str.append('\n') ;
    mTcpClient->write(str) ;
}

void TCPClient::on_pushButton_cleanMsgBox_clicked()
{
    ui->plainTextEdit->clear();
}

void TCPClient::on_pushButton_Quit_clicked()
{
    this->hide();
}
